home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
xlib06p1.zip
/
XLINE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-15
|
7KB
|
298 lines
#include "xinternl.h"
#include <conio.h>
#include <mem.h>
/*==================================================================
XLINE.CPP contains the code for simple bresenham lines in mode x.
Modified from w_modex.zip code, author unknown.
Modified March 1995 by Victor B. Putz.
===================================================================*/
WORD abPlaneMask[] = {
0x0102,
0x0202,
0x0402,
0x0802
};
extern unsigned char abLeftClipPlaneMask[];
extern unsigned char abRightClipPlaneMask[];
extern BYTE * pbVGABuffer;
extern int ScrnLogicalByteWidth;
void _HorizontalLine(
xPageHandle_t wOffset,
xScreenCoord_t iLeftX,
xScreenCoord_t iY,
int iLength,
xColor_t iColor
)
{
if ( iLength < 0 ) {
return;
}
BYTE * pb = pbVGABuffer + wOffset + ( ScrnLogicalByteWidth * iY ) + iLeftX / 4;
int iTemp;
//do the left part of the line
if ( iTemp = ( iLeftX & 3 ) ) {
outp( SC_INDEX, 0x02 );
outp( SC_INDEX + 1, abLeftClipPlaneMask[ iTemp ] );
*pb++ = ( BYTE )iColor;
iLength -= ( 4 - iTemp );
}
if ( iLength < 0 ) {
return;
}
//the middle
if ( iTemp = ( iLength >> 2 ) ) {
outpw( SC_INDEX, 0x0f02 );
iLength &= 3;
memset( pb, iColor, iTemp );
pb += iTemp;
}
//then the right part
if ( iLength ) {
outp( SC_INDEX, 0x02 );
outp( SC_INDEX + 1, abRightClipPlaneMask[ iLength ] );
*pb = ( BYTE )iColor;
}
}
void _VerticalLine(
xPageHandle_t wOffset,
xScreenCoord_t iX,
xScreenCoord_t iTopY,
int iLength,
xColor_t iColor
)
{
int iTemp = ( iX & 3 );
outpw(SC_INDEX, abPlaneMask[iTemp]);
BYTE * pbDest = pbVGABuffer + wOffset + ( iTopY * ScrnLogicalByteWidth ) + (iX / 4);
while (iLength--) {
*pbDest = ( BYTE )iColor;
pbDest += ScrnLogicalByteWidth;
}
}
void internal_xmajor(
BYTE * pbDest,
int iLength, //was short
int iYSkip, //was short
unsigned long ErrorAcc,
unsigned long ErrorAdj,
BYTE bColor
)
{
if (iLength) {
iLength--;
while (iLength--) {
*pbDest++ = bColor;
ErrorAcc += ErrorAdj;
if (ErrorAcc & ~0xFFFFL) {
ErrorAcc &= 0xFFFFL;
pbDest += iYSkip;
}
}
*pbDest = bColor;
}
}
void internal_middle(
BYTE *pbDest,
int iLength, //was short
int iYSkip, //was short
unsigned long ErrorAcc,
unsigned long ErrorAdj,
BYTE bColor
)
{
if (iLength) {
iLength--;
while (iLength--) {
*pbDest++ = bColor;
ErrorAcc += ErrorAdj;
pbDest += (iYSkip * (ErrorAcc >> 16));
ErrorAcc &= 0xFFFFL;
}
*pbDest = bColor;
}
}
void internal_ymajor(
BYTE *pbDest,
int iLength, //was short
int iYSkip, //was short
unsigned long ErrorAcc,
unsigned long ErrorAdj,
BYTE bColor
)
{
unsigned long TinyAdj;
int i;//was short
if (iLength) {
TinyAdj = (ErrorAdj >> 2);
ErrorAdj -= TinyAdj;
iLength--;
while (iLength--) {
ErrorAcc += TinyAdj;
i = (ErrorAcc >> 16);
ErrorAcc &= 0xFFFFL;
while (i--) {
*pbDest = bColor;
pbDest += iYSkip;
}
ErrorAcc += ErrorAdj;
pbDest += (iYSkip * (ErrorAcc >> 16)) + 1;
ErrorAcc &= 0xFFFFL;
}
ErrorAcc += TinyAdj;
i = (ErrorAcc >> 16);
while (i--) {
*pbDest = bColor;
pbDest += iYSkip;
}
}
}
void x_line( /* Draw a line, what else */
xScreenCoord_t x1,
xScreenCoord_t y1,
xScreenCoord_t x2,
xScreenCoord_t y2,
xColor_t color,
xPageHandle_t PageBase
)
{
unsigned long ErrorAcc, ErrorAdj, TinyAdj;
int i, DeltaX, DeltaY, yskip; //was short
int len[4]; //was short
BYTE * pbDest;
int iTemp;
// Mode X 4-way folded Bresenham line function - by David Boeren
//modified to fit XLIB by Victor Putz
// Make sure the line runs left to right by swapping ends if necessary
if (x1 > x2) {
iTemp = x1; x1 = x2; x2 = iTemp;
iTemp = y1; y1 = y2; y2 = iTemp;
}
DeltaX = (x2 - x1);
DeltaY = (y2 - y1);
if (DeltaY >= 0) {
yskip = ScrnLogicalByteWidth;
} else {
DeltaY = -DeltaY; // Make DeltaY positive
yskip = -ScrnLogicalByteWidth;
}
if (DeltaX == 0) {
// Vertical Line (and one pixel lines)
if (yskip > 0) {
_VerticalLine(PageBase, x1, y1, (DeltaY + 1), color);
} else {
_VerticalLine(PageBase, x1, y2, (DeltaY + 1), color);
}
return;
}
if (DeltaY == 0) {
// Horizontal Line
_HorizontalLine(PageBase, x1, y1, (DeltaX + 1), color);
return;
}
pbDest = pbVGABuffer + PageBase + ( y1 * ScrnLogicalByteWidth ) + (x1 / 4);
ErrorAcc = 0x8000;
// Length of sub-line in each plane
iTemp = (x1 & 3);
i = DeltaX + iTemp;
len[0] = ((i--) >> 2);
len[1] = ((i--) >> 2);
len[2] = ((i--) >> 2);
len[3] = (i >> 2) + 1;
for (i=iTemp; i < 3; i++) {
len[i]++;
}
if ((DeltaX >> 2) >= DeltaY) {
// X-Major line (0.00 < slope <= 0.25)
ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));
TinyAdj = (ErrorAdj >> 2);
while (i--) {
outpw(SC_INDEX, abPlaneMask[iTemp]);
internal_xmajor(pbDest, len[iTemp++], yskip, ErrorAcc, ErrorAdj, color);
if (iTemp == 4) {
iTemp = 0;
pbDest++;
}
ErrorAcc += TinyAdj;
if (ErrorAcc & ~0xFFFFL) {
ErrorAcc &= 0xFFFFL;
pbDest += yskip;
}
}
outpw(SC_INDEX, abPlaneMask[iTemp]);
internal_xmajor(pbDest, len[iTemp], yskip, ErrorAcc, ErrorAdj, color);
} else if (DeltaX >= DeltaY) {
// Middle line (0.25 < slope <= 1.00)
ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));
TinyAdj = (ErrorAdj >> 2);
while (i--) {
outpw(SC_INDEX, abPlaneMask[iTemp]);
internal_middle(pbDest, len[iTemp++], yskip, ErrorAcc, ErrorAdj, color);
if (iTemp == 4) {
iTemp = 0;
pbDest++;
}
ErrorAcc += TinyAdj;
if (ErrorAcc & ~0xFFFFL) {
pbDest += yskip;
ErrorAcc &= 0xFFFFL;
}
}
outpw(SC_INDEX, abPlaneMask[iTemp]);
internal_middle(pbDest, len[iTemp], yskip, ErrorAcc, ErrorAdj, color);
} else {
// Y-Major line (slope > 1)
ErrorAdj = ((((unsigned long)(DeltaY+1) << 18) /
(unsigned long)(DeltaX+1)));
TinyAdj = (ErrorAdj >> 2);
while (i--) {
outpw(SC_INDEX, abPlaneMask[iTemp]);
internal_ymajor(pbDest, len[iTemp++], yskip, ErrorAcc, ErrorAdj, color);
if (iTemp == 4) {
iTemp = 0;
pbDest++;
}
ErrorAcc += TinyAdj;
pbDest += (yskip * (ErrorAcc >> 16));
ErrorAcc &= 0xFFFFL;
}
outpw(SC_INDEX, abPlaneMask[iTemp]);
internal_ymajor(pbDest, len[iTemp], yskip, ErrorAcc, ErrorAdj, color);
}
}